\section{字符编码}

\subsection{ASCII与ISO/IEC 646}
ASCII（American Standard Code for Information Interchange，美国信息交换标准代码）是基于拉丁字母的一套电脑编码系统。它主要用于显示现代英语，而其扩展版本EASCII则可以勉强显示其他西欧语言。它是现今最通用的单字节编码系统（但是有被Unicode追上的迹象），并等同于国际标准ISO/IEC 646。ISO/IEC 646是国际标准化组织（ISO）和国际电工委员会（IEC）于1972年制订的标准。它是一个 7-位元字符的字集，来自数个国家标准，最主要来自美国的 ASCII（美国信息互换标准代码）。

ASCII第一次以规范标准的型态发表是在1967年，最后一次更新则是在1986年，至今为止共定义了128个字符；其中33个字符无法显示（这是以现今操作系统为依归，但在DOS模式下可显示出一些诸如笑脸、扑克牌花式等8-bit符号），且这33个字符多数都已是陈废的控制字符。控制字符的用途主要是用来操控已经处理过的文字。在33个字符之外的是95个可显示的字符，包含用键盘敲下空白键所产生的空白字符也算1个可显示字符（显示为空白）。

\subsection{ISO 8859}
ISO 8859，全称ISO/IEC 8859，是国际标准化组织（ISO）及国际电工委员会（IEC）联合制定的一系列8位字符集的标准，现时定义了15个字符集。这15个字符集是互斥的。如Latin-1和Latin-2而言相同数字代表不同字符。除了使用拉丁字母的语言外，使用西里尔字母的东欧语言、希腊语、泰语、现代阿拉伯语、希伯来语等，都可以使用这个形式来储存及表示。

ISO 8859-1，正式编号为ISO/IEC 8859-1:1998，又称Latin-1或“西欧语言”，是国际标准化组织内ISO/IEC 8859的第一个8位字符集。它以ASCII为基础，在空置的0xA0-0xFF的范围内，加入96个字母及符号，藉以供使用附加符号的拉丁字母语言使用。

ISO 8859-2，正式编号为ISO/IEC 8859-2:1999，又称Latin-2或“中欧语言”，是国际标准化组织内ISO/IEC 8859的其中一个8位字符集。

ISO 8859-15字符集，也称为 Latin-9，或者被匿称为 Latin-0，它将 Latin-1中较少用到的符号删除，换成当初遗漏的法文和芬兰字母；还有，把英镑和日元之间的金钱符号，换成了欧盟货币符号。

\subsection{通用字符集}
通用字符集（Universal Character Set，UCS）是由ISO制定的ISO 10646（或称ISO/IEC 10646）标准所定义的标准字符集。通用字符集是所有包括了其他字符集。它保证了与其他字符集的双向兼容，即，如果你将任何文本字符串翻译到UCS格式，然后再翻译回原编码，你不会丢失任何信息。UCS包含了已知语言的所有字符。除了拉丁语、希腊语、斯拉夫语、希伯来语、阿拉伯语、亚美尼亚语、格鲁吉亚语，还包括中文、日文、韩文这样的方块文字，UCS还包括大量的图形、印刷、数学、科学符号。ISO/IEC 10646定义了一个31位的字符集。ISO/IEC 10646-1标准第一次发表于1993年，现在的公开版本是ISO/IEC 10646-1:2000。ISO/IEC 10646-2在2001年发表。

UCS不仅给每个字符分配一个代码，而且赋予了一个正式的名字。表示一个UCS或Unicode值的十六进制数通常在前面加上“U+”，例如“U+0041”代表字符“A”。

\subsection{Unicode}
位于美国加州的Unicode组织允许任何愿意支付会员费用的公司或是个人加入，其成员包含了主要的电脑软硬件厂商，例如奥多比系统、苹果公司、惠普、IBM、微软、施乐等。20世纪80年代末，组成Unicode组织的商业机构，和国际合作的国际标准化组织（International Organization for Standardization，简称ISO）因为电脑普及和资讯国际化的前提下，分别各自成立了Unicode组织和ISO-10646工作小组。他们不久便发现对方机构的存在，大家为着相同的目的而工作，于是两个组织便共同合作开发适用于各国语言的通用码，而且“相当有默契地”各自发表Unicode和ISO-10646字集。虽然实际上两者的字集编码相同，但实质上两者确实为两个不同的标准。

目前，几乎所有电脑系统都支持基本拉丁字母，并各自支持不同的其他编码方式。Unicode为了和它们相互兼容，其首256字符保留给ISO 8859-1所定义的字符，使既有的西欧语系文字的转换不需特别考量；并且把大量相同的字符重复编到不同的字符码中去，使得旧有纷杂的编码方式得以和Unicode编码间互相直接转换，而不会遗失任何资讯。

目前实际应用的统一码版本对应于UCS-2，使用16位的编码空间。也就是每个字符占用2个字节。上述16位统一码字符构成基本多文种平面（Basic Multilingual Plane，简称BMP），包含了常见的CJK字。最新（但未实际广泛使用）的统一码版本定义了16个辅助平面，两者合起来至少需要占据21位的编码空间，比3字节略少。但事实上辅助平面字符仍然占用4字节编码空间，与UCS-4保持一致。目前辅助平面的工作主要集中在第二和第三平面的中日韩统一表意文字中，因此包括GBK、GB18030、Big5等简体中文、繁体中文、日文、韩文以及越南喃字的各种编码与Unicode的协调性被重点关注。

Unicode的码空间从U+0000到U+10FFFF，共有1,112,064个码位(code point)可用来映射字符. Unicode的码空间可以划分为17个平面(plane)，每个平面包含216(65,536)个码位。每个平面的码位可表示为从U+xx0000到U+xxFFFF, 其中xx表示十六进制值从0016 到1016，共计17个平面。第一个平面成为基本多文种平面（Basic Multilingual Plane, BMP），或称第零平面（Plane 0）。其他平面称为辅助平面(Supplementary Planes)。基本多语言平面内，从U+D800到U+DFFF之间的码位区段是永久保留不映射到字符，因此UTF-16利用保留下来的0xD800-0xDFFF区段的码位来对辅助平面的字符的码位进行编码。

Unicode依随着UCS的标准而发展。目前最新的版本为第六版，已收入了超过十万个字符（第十万个字符在2005年获采纳）。Unicode备受认可，并广泛地应用于电脑软件的国际化与本地化过程。有很多新科技，如XML、Java，以及现代的操作系统，都采用Unicode编码。

\subsection{UTF}
Unicode的实现方式不同于编码方式。一个字符的Unicode编码是确定的。但是在实际传输过程中，由于不同系统平台的设计不一定一致，以及出于节省空间的目的，对Unicode编码的实现方式有所不同。Unicode的实现方式称为Unicode转换格式（Unicode Transformation Format，简称为UTF）。

例如，如果一个仅包含基本7位ASCII字符的Unicode文件，如果每个字符都使用2字节的原Unicode编码传输，其第一字节的8位始终为0。这就造成了比较大的浪费。对于这种情况，可以使用UTF-8编码，这是一种变长编码，它将基本7位ASCII字符仍用7位编码表示，占用一个字节（首位补0）。而遇到与其他Unicode字符混合的情况，将按一定算法转换，每个字符使用1-3个字节编码，并利用首位为0或1进行识别。这样对以7位ASCII字符为主的西文文档就大大节省了编码长度。类似的，对未来会出现的需要4个字节的辅助平面字符和其他UCS-4扩充字符，2字节编码的UTF-16也需要通过一定的算法进行转换。再如，如果直接使用与Unicode编码一致（仅限于BMP字符）的UTF-16编码，由于每个字符占用了两个字节，在麦金塔电脑 (Mac)机和个人电脑上，对字节顺序的理解是不一致的。

目前在PC机上的Windows系统和Linux系统对于UTF-16编码默认使用UTF-16 LE。此外Unicode的实现方式还包括UTF-7、Punycode、CESU-8、SCSU、UTF-32、GB18030等，这些实现方式有些仅在一定的国家和地区使用，有些则属于未来的规划方式。目前通用的实现方式是UTF-16小端序（LE）、UTF-16大端序（BE）和UTF-8。

\subsection{UTF-8}
UTF-8（8-bit Unicode Transformation Format）是一种针对Unicode的可变长度字符编码（定长码），也是一种前缀码。它可以用来表示Unicode标准中的任何字符，且其编码中的第一个字节仍与ASCII相容，这使得原来处理ASCII字符的软件无须或只须做少部份修改，即可继续使用。因此，它逐渐成为电子邮件、网页及其他储存或传送文字的应用中，优先采用的编码。互联网工程工作小组（IETF）要求所有互联网协议都必须支持UTF-8编码。互联网邮件联盟（IMC）建议所有电子邮件软件都支持UTF-8编码。

UTF-8使用一至四个字节为每个字符编码：128个US-ASCII字符只需一个字节编码（Unicode范围由U+0000至U+007F）。带有附加符号的拉丁文、希腊文、西里尔字母、亚美尼亚语、希伯来文、阿拉伯文、叙利亚文及它拿字母则需要二个字节编码（Unicode范围由U+0080至U+07FF）。其他基本多文种平面（BMP）中的字符（这包含了大部分常用字）使用三个字节编码。其他极少使用的Unicode 辅助平面的字符使用四字节编码。

每个使用UTF-8储存的字符，除了第一个字节外，其余字节的头两个位元都是以"10"开始，使文字处理器能够较快地找出每个字符的开始位置。在ASCII码的范围，用一个字节表示。大于ASCII码的，就会由上面的第一字节的前几位表示该unicode字符的长度，比如110xxxxxx前三位的二进制表示告诉我们这是个2BYTE的UNICODE字符；1110xxxx是个三位的UNICODE字符，依此类推；第一个字节的开头"1"的数目就是整个串中字节的数目。ASCII字母继续使用1字节储存，重音文字、希腊字母或西里尔字母等使用2字节来储存，而常用的汉字就要使用3字节。辅助平面字符则使用4字节。


\subsection{UTF-16}
UTF-16是Unicode字符集的一种转换方式，即把Unicode的码位转换为16比特长的码元序列，以用于数据存储或传递。UTF-16正式定义于ISO/IEC 10646-1的附录C。

BMP内，从U+D800到U+DFFF之间的码位区段是永久保留不映射到字符，因此UTF-16利用保留下来的0xD800-0xDFFF区段的码位来对辅助平面的字符的码位进行编码。

从U+0000至U+D7FF以及从U+E000至U+FFFF的码位，UTF-16与UCS-2编码这个范围内的码位为单个16比特长的码元，数值等价于对应的码位. BMP中的这些码位是仅有的码位可以在UCS-2被表示.从U+10000到U+10FFFF的码位为辅助平面(Supplementary Planes)中的码位，在UTF-16中被编码为一对16比特长的码元(即32bit,4Bytes)，称作代理对(surrogate pair)。

UTF-16的大尾序和小尾序储存形式都在用。一般来说，以Macintosh制作或储存的文字使用大尾序格式，以Microsoft或Linux制作或储存的文字使用小尾序格式。

\subsection{大小端和BOM}

字节序，又称端序，尾序（英语：Endianness）。在计算机科学领域中，字节序是指存放多字节数据的字节（byte）的顺序，典型的情况是整数在内存中的存放方式和网络传输的传输顺序。Endianness有时候也可以用指位序（bit）。一般而言，字节序指示了一个UCS-2字符的哪个字节存储在低地址。如果LSByte在MSByte的前面，即LSB为低地址，则该字节序是小端序；反之则是大端序。

网络传输一般采用大端序，也被称之为网络字节序，或网络序。IP协议中定义大端序为网络字节序。

字节顺序标记（英语：byte-order mark，BOM）是位于码点U+FEFF的统一码字符的名称。当以UTF-16或UTF-32来将UCS/统一码字符所组成的字串编码时，这个字符被用来标示其字节序。它常被用来当做标示文件是以UTF-8、UTF-16或UTF-32编码的记号。

统一码中，值为U+FFFE的码位被保证将不会被指定成一个统一码字符。这意味着0xFF、0xFE将只能被解释成小尾序中的U+FEFF。

字节顺序标记U+FEFF字符在UTF-8中被表示为序列EF BB BF。许多Windows程序（包括Windows记事本）在UTF-8编码的档案的开首加入一段字节串EF BB BF。这是字节顺序记号U+FEFF的UTF-8编码结果。对于没有预期要处理UTF-8的文字编辑器和浏览器会显示成ISO-8859-1字符串"ï»¿"。

\subsection{汉字内码}

在计算机科学及相关领域当中，内码指的是“将资讯编码后，透过某种方式储存在特定记忆装置时，装置内部的编码形式”。在以往的英文系统中，内码为ASCII。 在繁体中文系统中，目前常用的内码为大五码。在简体中文系统中，内码则为国标码。为了软件开发方便，如国际化与在地化，现在许多系统会使用统一码做为内码，常见的Windows、麦金塔、Linux皆如此。许多语言也采用统一码为内码，如Java、Python 3。

内码是指整机汉字系统中使用的二进制字符编码，是沟通输入、输出与系统平台之间的交换码，通过内码可以达到通用和高效率传输文本的目的。比如MS Word中所存储和调用的就是内码而非图形文字。英文ASCII 字符采用一个字节的内码表示，中文字符如国标字符集中，GB2312、GB12345、GB13000皆用双字节内码，GB18030（27,533汉字）双字节内码汉字为20,902个，其余6,631个汉字用四字节内码。

汉字内码主要有：GB码(1980年国家公布的简体汉字编码方案，在大陆、新加坡得到广泛的使用，也称国标码)，GBK码(简体版的Win95和Win98都是使用GBK作系统内码)，BIG5码（针对繁体汉字的汉字编码，目前在台湾、香港的电脑系统中得到普遍应用)，HZ码（在Internet上广泛使用的一种汉字编码），ISO－2022CJK码，Unicode码。

\subsection{GB2312与区位码}
GB 2312 或 GB 2312-80 是中国国家标准简体中文字符集，全称《信息交换用汉字编码字符集·基本集》，又称GB0，由中国国家标准总局发布，1981年5月1日实施。GB2312编码通行于中国大陆；新加坡等地也采用此编码。中国大陆几乎所有的中文系统和国际化的软件都支持GB 2312。GB 2312标准共收录6763个汉字，覆盖中国大陆99.75\%的使用频率同时收录了包括拉丁字母、俄语西里尔字母在内的682个字符。对于人名、古汉语等方面出现的罕用字，GB 2312不能处理，这导致了后来GBK及GB 18030汉字字符集的出现。

GB 2312中对所收汉字进行了“分区”处理，每区含有94个汉字/符号。这种表示方式也称为区位码。01-09区为特殊符号。16-55区为一级汉字，按拼音排序。56-87区为二级汉字，按部首排序。10-15区及88-94区则未有编码。举例来说，“啊”字是GB2312之中的第一个汉字，它的区位码就是1601。国标码是一个四位十六进制数，区位码是一个四位的十进制数，每个国标码或区位码都对应着一个唯一的汉字或符号，但因为十六进制数我们很少用到，所以大家常用的是区位码，它的前两位叫做区码，后两位叫做位码。

EUC-CN是GB 2312最常用的表示方法，兼容ASCII。浏览器编码表上的“GB2312”，通常都是指“EUC-CN”表示法。GB 2312非ASCII字符使用两个字节来表示。“第一位字节”使用0xA1-0xF7,“第二位字节”使用0xA1-0xFE.举例来说，“啊”字的区位码是1601。在EUC-CN之中，它把0xA0+16=0xB0,0xA0+1=0xA1，得出0xB0A1。

HZ is another encoding of GB2312 that is used mostly for Usenet postings.

Compared to UTF-8, GB2312 (whether native or encoded in EUC-CN) is more storage efficient, this because no bits are reserved to indicate three or four byte sequences, and no bit is reserved for detecting tailing bytes.

\subsection{微软GBK}
GBK即汉字内码扩展规范，K为汉语拼音 Kuo Zhan（扩展）中“扩”字的声母。
1993年，Unicode 1.1版本推出，收录中国大陆、台湾、日本及韩国通用字符集的汉字，总共有20,902个。中国大陆订定了等同于Unicode 1.1版本的“GB13000.1-93”“信息技术通用多八位编码字符集（UCS）第一部分：体系结构与基本多文种平面”。

微软利用GB 2312-80未使用的编码空间，收录GB 13000.1-93全部字符制定了GBK编码。根据微软资料，GBK是对GB2312-80的扩展，也就是CP936字码表 (Code Page 936)的扩展（之前CP936和GB 2312-80一模一样），最早实现于Windows 95简体中文版。虽然GBK收录GB 13000.1-93的全部字符，但编码方式并不相同。GBK自身并非国家标准，只是曾由国家技术监督局标准化司、电子工业部科技与质量监督司公布为“技术规范指导性文件”。原始GB13000一直未被业界采用，后续国家标准GB18030技术上兼容GBK而非GB13000。

字符有一字节和双字节编码，00–7F范围内是一位，和ASCII保持一致，此范围内严格上说有96个文字和32个控制符号。之后的双字节中，前一字节是双字节的第一位。总体上说第一字节的范围是81–FE（也就是不含80和FF），第二字节的一部分领域在40–7E，其他领域在80–FE。

GBK向下完全兼容GB2312-80编码。 支持GB2312-80编码不支持的部分中文姓，中文繁体，日文假名，还包括希腊字母以及俄语字母等字母。不过这种编码不支持韩国字，也是其在实际使用中与unicode编码相比欠缺的部分。微软的CP936通常被视为等同GBK，连 IANA 也以“CP936”为“GBK”之别名。事实上比较起来， GBK 定义之字符较 CP936 多出95字。

\subsection{GB18030}
GB 18030，最新版本为GB 18030-2005，其全称为中华人民共和国国家标准GB 18030-2005《信息技术 中文编码字符集》,与GB 2312-1980完全兼容，与GBK基本兼容，支持GB 13000及Unicode的全部统一汉字，共收录汉字70244个。

此标准中，单字节的部分收录了GB/T 11383-1989的0x00到0x7F全部128个字符。双字节部分采用两个八位二进制位串表示一个字符，其首字节码位从0x81至0xFE，尾字节码位分别是0x40至0x7E和0x80至0xFE。四字节部分采用GB/T 11383-1989未采用的0x30至0x39作为对双字节编码的扩充的后缀。这样扩充的四字节编码，其范围为0x81308130到0xFE39FE39。四字节字符的第一个字节的编码为0x81至0xFE；第二个字节的编码范围为0x30至0x39；第三个字节编码范围为0x81至0xFE；第四个字节编码范围为0x30至0x39。

GB18030与Unicode的关系：GB 18030是一种对字符集的多字节编码格式，相当于UTF-8（对Unicode码点(code point)的编码传输格式），而且都是向后兼容ASCII，并且能表示所有的Unicode码点。GB 18030的四字节编码共有1,587,600 (126×10×126×10), 足以覆盖Unicode的1,111,998 (17×65536 − 2048 surrogates − 66 noncharacters)码点。此外，GB18030还向后兼容了GB 2312与GBK编码。与Unicode码点的映射关系(mapping)一部分要查表，其它可以通过算法求出，这与UTF-8相比不够方便。


\subsection{ISO 2022}

全称ISO/IEC 2022，由国际标准化组织（ISO）及国际电工委员会（IEC）联合制定，是一个使用7位编码表示汉语文字、日语文字或朝鲜文字的方法。
ISO 2022等同于欧洲标准组织（ECMA）的ECMA-35、中国国标GB 2312、日本工业规格JIS X 0202（旧称JIS C 6228）及韩国工业规格KS X 1004（旧称KS C 5620）。拉丁字母、希腊字母、西里尔字母、希伯来字母等的语文，由于只使用数十个字母，传统上均使用8位编码的ISO/IEC 8859标准来表示。但由于汉语、日语及朝鲜语字数众多，无法用单一个8位字符来表达，故需要多于一个字节来代表一个字。于是，ISO 2022就设计出来让汉语、日语及朝鲜语可以使用数个7位编码的字符来示。ISO 2022使用“逃逸字串”（Escape sequence）。逃逸字串由1个“ESC”字符（0x1B），再由两至三个字串组成。此标记代表它后面的字符，属于下表字符集的文字。





























